package controllers

import (
	"context"
	"errors"
	"github.com/gin-gonic/gin"
	"go.didapinche.com/foundation/plat-echo/app/ops/models"
	"go.didapinche.com/foundation/plat-echo/app/ops/services"
	"go.didapinche.com/foundation/plat-echo/pkg/constants"
	"go.didapinche.com/uic"
	"go.uber.org/zap"
	"net/http"
	"strconv"
)

type DashboardController struct {
	service services.DashboardService
	logger  *zap.Logger
}

func NewDashboardController(service services.DashboardService, logger *zap.Logger) *DashboardController {
	return &DashboardController{
		service: service,
		logger:  logger.With(zap.String("type", "controller.dashboard")),
	}
}

func (ctl *DashboardController) FindAll(c *gin.Context) {
	all, err := ctl.service.FindAll(c.Request.Context())
	if err != nil {
		if errors.Is(err, context.Canceled) {
			ctl.logger.Error("context canceled", zap.Error(err))
			c.Status(constants.StatusRequestCanceled)
			return
		}
		ctl.logger.Error("call DashboardService.FindAll() error", zap.Error(err))
		c.String(http.StatusInternalServerError, "call DashboardService.FindAll() error:%v", err)
		return
	}
	c.JSON(http.StatusOK, all)
}

func (ctl *DashboardController) Create(c *gin.Context) {
	req := new(models.Dashboard)
	if err := c.BindJSON(req); err != nil {
		ctl.logger.Error("bind params error", zap.Error(err))
		c.String(http.StatusBadRequest, "bind params error:%v", err)
		return
	}
	name := c.GetString(uic.KeyUserName)
	req.Owner = name
	dashboard, err := ctl.service.Create(c.Request.Context(), req)
	if err != nil {
		if errors.Is(err, context.Canceled) {
			ctl.logger.Error("context canceled", zap.Error(err))
			c.Status(constants.StatusRequestCanceled)
			return
		}
		ctl.logger.Error("call DashboardService.Create error", zap.Error(err))
		c.String(http.StatusInternalServerError, "call DashboardService.Create error:%v", err)
		return
	}
	c.JSON(http.StatusOK, dashboard)
}

func (ctl *DashboardController) Update(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 64)
	if err != nil {
		ctl.logger.Error("parse id error", zap.Error(err))
		c.String(http.StatusBadRequest, "parse id err:%v", err)
		return
	}
	req := new(models.Dashboard)
	if err := c.BindJSON(req); err != nil {
		ctl.logger.Error("bind params error", zap.Error(err))
		c.String(http.StatusBadRequest, "bind params error:%v", err)
		return
	}
	req.ID = id
	dashboard, err := ctl.service.Update(c.Request.Context(), req)
	if err != nil {
		if errors.Is(err, context.Canceled) {
			ctl.logger.Error("context canceled", zap.Error(err))
			c.Status(constants.StatusRequestCanceled)
			return
		}
		ctl.logger.Error("call DashboardService.Save error", zap.Error(err))
		c.String(http.StatusInternalServerError, "call DashboardService.Save error:%v", err)
		return
	}
	c.JSON(http.StatusOK, dashboard)
}

func (ctl *DashboardController) Delete(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 64)
	if err != nil {
		ctl.logger.Error("parse id err", zap.Error(err))
		c.String(http.StatusBadRequest, "parse id err:%v", err)
		return
	}
	err = ctl.service.DeleteByID(c.Request.Context(), id)
	if err != nil {
		if errors.Is(err, context.Canceled) {
			ctl.logger.Error("context canceled", zap.Error(err))
			c.Status(constants.StatusRequestCanceled)
			return
		}
		ctl.logger.Error("call DashboardService.Delete error", zap.Error(err))
		c.String(http.StatusInternalServerError, "call DashboardService.Delete error:%v", err)
		return
	}
	c.JSON(http.StatusOK, "ok")
}
